package com.ruoyi.aitcommon.utils;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.aitcommon.vo.AggMap;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;

public class ListMapUtils {
	/**
	 * 对Map集合所有字段进行过滤
	 * @param mapList map集合
	 * @param filter 过滤值
	 * @return
	 */
	public static List<Map<String, Object>> MapFilter(List<Map<String, Object>> mapList, String filter) {
		List<Map<String, Object>> filteredList = new ArrayList<>();
		for (Map<String, Object> record : mapList) {
			boolean match = false;
			for (Object value : record.values()) {
				if(ObjUtils.isBlank(value)) continue;
				if (value.toString().contains(filter)) {
					match = true;
					break; // 一旦发现匹配，无需继续检查此记录的其他字段
				}
			}
			if (match) {
				filteredList.add(record);
			}
		}
		return filteredList;
	}

	public static List<Map<String,Object>> newListMap(){
		return new ArrayList<Map<String,Object>>();
	}
	
	public static List<Map<String,Object>> array2Map(List<Object> arr){
		List<Map<String,Object>> retlist=new ArrayList<Map<String,Object>>();
		for(Object item : arr) {
			Map<String,Object> retmap=(Map<String,Object>)item;
			retlist.add(retmap);
		}
		return retlist;
	}
	
	public static List<Map<String,Object>> newListMap(List<Map<String,Object>> oldlist
			,MapEntryProcessor process){
		List<Map<String, Object>> retlist = newListMap();
		for(Map<String,Object> map:oldlist) {
			Map<String,Object> retmap=new LinkedHashMap<String,Object>();
			for(Entry<String,Object> entry:map.entrySet()) {
				Object[] ret = process.process(entry);
				retmap.put(ret[0].toString(), ret[1]);
			}
			retlist.add(retmap);
		}
		return retlist;
	}

	/**
	 * 增对每行,map中的每一项,单独处理
	 * @param maplist
	 * @param process
	 */
	public static void eachListMap(List<Map<String,Object>> maplist
			,MapEntryProcessor process) {
		for(Map<String,Object> map:maplist) {
			Set<Entry<String,Object>> entrySet = map.entrySet();
			for(Entry<String,Object> entry:entrySet) {
				process.process(entry);
			}
		}
	}
	
	/**
	 * listmap中增加字段
	 * @param listmap
	 * @param key
	 * @param val
	 * @return
	 */
	public static List<Map<String,Object>> put(List<Map<String,Object>> listmap,String key,Object val){
		if(listmap==null) return null;
		for(Map<String,Object> map:listmap) {
			map.put(key, val);
		}
		return listmap;
	}
	
	/**
	 * listmap中增加key字段
	 * @param datas 数据集合
	 * @param map key字段映射
	 * <pre>
	 * 举例:
	 * "keymap":{
			"keyField":"pkey",
			"keyValue":"${purchaseCode}-${materialCode}"
		}
	 * </pre>
	 * @return 包含key的数据集合
	 * @throws Exception 
	 */
	public static List<Map<String,Object>> putKey(List<Map<String,Object>> datas,Map<String,Object> map) throws Exception{
		if(datas==null) return null;
		ExceptionUtils.checkBlankOrUndefined(map, "map映射为空");
		ExceptionUtils.checkBlankOrUndefined(map.get("keyField"), "map.keyField为空");
		ExceptionUtils.checkBlankOrUndefined(map.get("keyValue"), "map.keyValue为空");
		
		for(Map<String,Object> data:datas) {
			String key=map.get("keyField").toString();
			Object value=FlowParamUtils.getFlowParamsValue(map.get("keyValue").toString(), data);
			data.put(key, value);
		}
		return datas;
	}
	
	/**
	 * 从list中删除第一条,并返回新list
	 * @param list
	 * @return
	 */
	private static List<Map<String,Object>> pop(List<Map<String,Object>> list){
		if(list==null||list.size()==0||list.size()==1) return null;
		
		List<Map<String,Object>> retlist=new ArrayList<Map<String,Object>>();
		for(int i=0;i<list.size();i++) {
			if(i>0) {
				retlist.add(list.get(i));
			}
		}
		return retlist;
	}

	/**
	 * 获取第一行的固定字段值
	 * @param datas 传入数据
	 * @param key 固定字段
	 * @return 第一行的值
	 */
	public static Object getColumnValue(List<Map<String,Object>> datas,String key) {
		if(ObjectUtil.isEmpty(datas))
			return null;
		else
			return datas.get(0).get(key);
	}
	
	public static List<Map<String,Object>> fromJSONArray(JSONArray array){
		if(array==null||array.size()==0) return null;
		List<Map<String,Object>> retlist=new ArrayList<Map<String, Object>>();
		for(int i=0;i<array.size();i++) {
			JSONObject item=array.getJSONObject(i);
			retlist.add(item);
		}
		return retlist;
	}
	
//	将ResultSet转换为Map List
	public static List<Map<String, Object>> fromResultSet(ResultSet ret) throws SQLException{
    	List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    	if(ret==null)
    		return null;
    	
    	ResultSetMetaData meta = ret.getMetaData();
    	int cot = meta.getColumnCount();
    	
    	while(ret.next()) {
    		Map<String, Object> map = new LinkedHashMap<String, Object>();
    		for(int i = 0; i < cot; i++) {
    			map.put(meta.getColumnLabel(i + 1), ret.getObject(i + 1));
    		}
    		list.add(map);
    	}
    	return list;
    }
	
	/**
	 * 将数据中的key替换为映射中的value(key->value)
	 * @param datas 数据集合
	 * @param map 映射
	 * @return 转换后的数据
	 */
	public static List<Map<String,Object>> transObjectKeytoValue(List<Map<String,Object>> datas
			,Map<String,Object> map){
		List<Map<String,Object>> retlist=new ArrayList<Map<String,Object>>();
		for(Map<String,Object> item:datas) {
			Map<String, Object> value = MapUtils.transObjectKeytoValue(item, map);
			retlist.add(value);
		}
		return retlist;
	}
	
	/**
	 * 将数据中的key替换为映射中的key(value->key)
	 * @param datas 数据集合
	 * @param map 映射
	 * @return 转换后的数据
	 */
	public static List<Map<String,Object>> transObjectValuetoKey(List<Map<String,Object>> datas
			,Map<String,Object> map){
		List<Map<String,Object>> retlist=new ArrayList<Map<String,Object>>();
		for(Map<String,Object> item:datas) {
			Map<String, Object> value = MapUtils.transObjectValuetoKey(item, map);
			retlist.add(value);
		}
		return retlist;
	}
	
	public static List<Map<String,Object>> agg2Map(List<AggMap> aggs){
		List<Map<String,Object>> retlist=new ArrayList<Map<String,Object>>();
		for(AggMap agg:aggs) {
			retlist.add(agg);
		}
		return retlist;
	}
	
	public static List<AggMap> map2Agg(List<Map<String,Object>> maps){
		List<AggMap> retlist=new ArrayList<AggMap>();
		for(Map<String,Object> map:maps) {
			retlist.add(new AggMap(map));
		}
		return retlist;
	}

	/**
	 * 将listmap转换为u9格式的listmap
	 * @param values sql返回的listmap
	 * @param fengge 分隔信息,类型list[{field:分隔字段,attr:属性字段,headkey:分组Key}]
	 * @param zuhe 组合字段,例如:#
	 * @return u9格式的listmap
	 * @throws Exception
	 */
	public static List<Map<String,Object>> transU9Map(List<Map<String,Object>> values
			,List<Map<String,Object>> fengge,String zuhe) throws Exception{
		if(values==null) return null;
//		ExceptionUtils.checkBlankOrUndefined(fengge, "fengge为空");
		ExceptionUtils.checkBlankOrUndefined(zuhe, "zuhe为空");
		
//		先处理组合字段
		List<Map<String,Object>> retlist=new ArrayList<Map<String,Object>>();
		for(Map<String,Object> inmap:values) {
			Map<String,Object> retmap=new LinkedHashMap<String,Object>();
			for(String key:inmap.keySet()) {
				if(key.contains(zuhe)) {
					//该字段是组合字段,需要包装成对象
					String path = StrUtil.replace(key, zuhe, ".");
					MapUtils.putPathObject(path, retmap, inmap.get(key));
				}else {
					//其他字段,直接赋值
					retmap.put(key, inmap.get(key));
				}
			}
			retlist.add(retmap);
		}
		
//		递归处理主子表
		retlist=transU9Tree(retlist,fengge);
		return retlist;
	}

	/**
	 * 依据分隔字段,将列表转换为主从表格式
	 * 举例:
	 * 列表数据 {DocNo=test1, Org#Code=001, fengge1=fengge1, ItemInfo#ItemCode=0301001.000002, Wh#Code=101, StoreUOMQty=20, CostPrice=11}
	 * 分隔 [{"field":"fengge1","headkey":"DocNo","attr":"MiscRcvTransLs"}]
	 * 主从表数据 {DocNo=test1, Org={Code=001}, MiscRcvTransLs=[{ItemInfo={ItemCode=0301001.000002}, Wh={Code=101}, StoreUOMQty=20, CostPrice=11}]}
	 * @param values
	 * @param fengge
	 * @return
	 * @throws Exception
	 */
	private static List<Map<String,Object>> transU9Tree(List<Map<String,Object>> values
			,List<Map<String,Object>> fengge) throws Exception{
		if(fengge==null||fengge.size()==0) return values;
		
		List<Map<String,Object>> retlist=new ArrayList<Map<String,Object>>();
		Map<String,Object> fkey=fengge.get(0);
		
		ExceptionUtils.checkBlankOrUndefined(fkey.get("headkey"), "fengge.headkey为空");
		ExceptionUtils.checkBlankOrUndefined(fkey.get("attr"), "fengge.attr为空");
		ExceptionUtils.checkBlankOrUndefined(fkey.get("field"), "fengge.field为空");
		
		String headkey=fkey.get("headkey").toString();
		String attr=fkey.get("attr").toString();
		String fenge=fkey.get("field").toString();

//		将list转化为agg
		List<AggMap> aggvos = transAggVO(values,headkey,fenge);
//		将agg按照U9树形格式处理
		for(AggMap agg:aggvos) {
			Map<String,Object> retmap=new LinkedHashMap<String,Object>();
//			表头属性处理
			retmap.putAll(agg.getHeadVO());
//			表体属性处理
			if(agg.getBodyVOS()!=null&&agg.getBodyVOS().size()>0) {
				List<Map<String,Object>> sublist=new ArrayList<Map<String,Object>>();
				sublist=agg.getBodyVOS();
//				分隔存在多个时,递归处理
				List<Map<String,Object>> fengge1=ListMapUtils.pop(fengge);
				if(fengge1!=null&&fengge1.size()>0) {
					sublist=transU9Tree(sublist,fengge1);
				}
//				按U9树形,设置行对象
				retmap.put(attr, sublist);
			}
			retlist.add(retmap);
		}
		return retlist;
	}
	
	
	/**
	 * 将集合转换为aggvo,包含表头,表体
	 * aggvo格式:
	 * {
	 * 	"headVO":{},
	 * 	"bodyVOS":[{}]
	 * }
	 * @param values 集合数据
	 * @param headkey 表头分组key
	 * @param fenge 分隔符
	 * @return agg集合
	 * @throws Exception
	 */
	public static List<AggMap> transAggVO(List<Map<String,Object>> values
			,String headkey,String fenge) throws Exception{
		if(values==null) return null;
		
		List<AggMap> retlist=new ArrayList<AggMap>();
		Map<String,AggMap> aggmap=new LinkedHashMap<String,AggMap>();
		
//		该循环处理表头
		String headvalue="";
		for(Map<String,Object> value:values) {
			if(StrUtil.isBlankIfStr(value.get(headkey))) {
				LogUtils.error("单头主键:[{}],查找字段为空!",headkey);
//				单头值为空,该条数据不处理
				continue;
			}
			if(!headvalue.equals(String.valueOf(value.get(headkey)))) {
//				产生新的表头
				headvalue=String.valueOf(value.get(headkey));
				Map<String,Object> headmap=new LinkedHashMap<String,Object>();
//				表头map
				for(String key:value.keySet()) {
//					字段和值都=分隔符时,确定为分隔字段
//					不区分大小写
//					遇到第一个分隔符就停止
					if(key.equalsIgnoreCase(fenge)&&String.valueOf(value.get(key)).equalsIgnoreCase(fenge))
						break;
					else
						headmap.put(key, value.get(key));
				}
				AggMap aggvo=new AggMap(headmap,null);
				aggmap.put(headvalue, aggvo);
			}
		}
		
//		该循环处理表体
		for(Map<String,Object> value:values) {
			final Object headObj = value.get(headkey);
			ExceptionUtils.checkBlankOrUndefined(headObj,"[{}]获取值为空",headkey);
			AggMap aggvo=aggmap.get(headObj.toString());
			if(aggvo==null) throw new Exception("aggVO转换出错");
			if(aggvo.getBodyVOS()==null)
				aggvo.setBodyVOS(new ArrayList<Map<String,Object>>());
			Map<String,Object> bodymap=new LinkedHashMap<String,Object>();
			boolean isbody=false;
			for(String key:value.keySet()) {
				if(isbody==false
						&&key.equalsIgnoreCase(fenge)
						&&value.get(key).toString().equalsIgnoreCase(fenge)) {
//					第一个分隔符跳过
					isbody=true;
					continue;
				}
				if(isbody) {
					bodymap.put(key, value.get(key));
				}
			}
			aggvo.getBodyVOS().add(bodymap);
		}
		
//		将aggmap转换为agglist
		for(String key:aggmap.keySet()) {
			retlist.add(aggmap.get(key));
		}
		return retlist;
	}
}
